from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.model_selection import train_test_split
import pandas as pd
import numpy as np

print("\n1. 数据预处理...")

# 加载数据
iris = load_iris()
X = iris.data  # 特征矩阵
y = iris.target  # 目标变量

# 创建DataFrame便于查看
feature_names = iris.feature_names
df = pd.DataFrame(X, columns=feature_names)
df['target'] = y

print("数据基本信息:")
print(f"数据集形状: {X.shape}")
print(f"特征名称: {feature_names}")
print(f"目标类别: {np.unique(y)}")

# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

print("\n标准化后的数据前5行:")
print(X_scaled[:5])

print("\n2. 分割数据")
# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(
    X_scaled, y, 
    test_size=0.3,      # 测试集占30%
    random_state=42,    # 随机种子确保结果可重现
    stratify=y         # 分层抽样保持类别比例
)

print(f"训练集大小: {X_train.shape}")
print(f"测试集大小: {X_test.shape}")
print(f"训练集类别分布: {np.bincount(y_train)}")
print(f"测试集类别分布: {np.bincount(y_test)}")

print("\n3. 训练模型")
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC

# 初始化不同分类器
models = {
    '逻辑回归': LogisticRegression(random_state=42),
    '随机森林': RandomForestClassifier(n_estimators=100, random_state=42),
    '支持向量机': SVC(kernel='rbf', random_state=42)
}

# 训练所有模型
trained_models = {}
for name, model in models.items():
    model.fit(X_train, y_train)
    trained_models[name] = model
    print(f"{name} 训练完成")

print("\n4. 验证模型")
from sklearn.model_selection import cross_val_score
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns

# 交叉验证评估
print("交叉验证结果（准确率）:")
for name, model in trained_models.items():
    scores = cross_val_score(model, X_train, y_train, cv=5)
    print(f"{name}: {scores.mean():.4f} (+/- {scores.std() * 2:.4f})")

# 在测试集上评估最佳模型
best_model = trained_models['随机森林']
y_pred = best_model.predict(X_test)

print("\n测试集性能评估:")
print(classification_report(y_test, y_pred))

print("\n5. 测试模型")
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

# 计算各项指标
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred, average='weighted')
recall = recall_score(y_test, y_pred, average='weighted')
f1 = f1_score(y_test, y_pred, average='weighted')

print("模型测试结果:")
print(f"准确率: {accuracy:.4f}")
print(f"精确率: {precision:.4f}")
print(f"召回率: {recall:.4f}")
print(f"F1分数: {f1:.4f}")

print("\n6. 使用模型")
# 模拟新数据预测
new_data = np.array([[5.1, 3.5, 1.4, 0.2],  # 新样本1
                     [6.2, 2.9, 4.3, 1.3]]) # 新样本2

# 标准化新数据（使用之前的scaler）
new_data_scaled = scaler.transform(new_data)

# 预测新数据
predictions = best_model.predict(new_data_scaled)
predicted_species = [iris.target_names[p] for p in predictions]

print("新数据预测结果:")
for i, (data, pred) in enumerate(zip(new_data, predicted_species)):
    print(f"样本{i+1}: {data} -> {pred}")

print("\n7. 调优模型")    
from sklearn.model_selection import GridSearchCV

# 定义参数网格
param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [None, 10, 20],
    'min_samples_split': [2, 5, 10]
}

# 网格搜索
grid_search = GridSearchCV(
    RandomForestClassifier(random_state=42),
    param_grid,
    cv=5,
    scoring='accuracy',
    n_jobs=-1
)

grid_search.fit(X_train, y_train)

print("最佳参数组合:")
print(grid_search.best_params_)
print(f"最佳交叉验证分数: {grid_search.best_score_:.4f}")

# 使用最佳模型进行预测
best_rf_model = grid_search.best_estimator_
y_pred_tuned = best_rf_model.predict(X_test)
tuned_accuracy = accuracy_score(y_test, y_pred_tuned)

print(f"调优后测试集准确率: {tuned_accuracy:.4f}")



